package web.operator;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import web.annotation.Param;
import web.annotation.Type;
import web.clazz.Clazz;

/**用于处理Controller注解，通过方法{@link #loadClass}将Controller信息存到{@link #Sets}中。
 * @author 乐渊
 * @version 1.0
 * @see ClassScanner
 * */
public class TypeOperator extends ClassOperator {
	
	public static Set<Clazz> Types;
	
	/**初始化，记录Controller注解信息。
	 * @param packageNames 包名数组
	 * {@link #loadClass(Set)}
	 * */
	public TypeOperator(){
		Types = loadClass(Sets);
	}
	
	/**加载所有含注解标签的Controller
	 * @param SetClazz
	 * @return sets
	 * */
	private Set<Clazz> loadClass(Set<Clazz> SetClazz) {
		Set<Clazz> sets = new HashSet<>();
		SetClazz.forEach(clazz ->{
			/* 旧写法 Annotation[] annClazz =  clazz.getClazz().getAnnotations();
			 * 先获取注解数组，再取第一个的值判断是否是Type的实例，在进行相应操作,下同*/
			
			@SuppressWarnings("unchecked")
			Type type = (Type) clazz.getClazz().getAnnotation(Type.class);
			
			if(type != null ){
				//<方法别名,方法实例>
				Map<String,Method> mapMethod = new HashMap<>();
				//<方法别名、是否返回页面>
				Map<String,Boolean> mapMReturnType = new HashMap<>();
				//<方法别名,参数集>
				Map<String,List<String>> mapParam = new HashMap<>();
				//<变量名,变量的get方法>
				Map<String,Method> members = new HashMap<>();
				
				if("".equals(type.value())){//存储类的别名 默认为首字母小写的类名
					String cn = clazz.getClazz().getName();
					cn = cn.substring(cn.lastIndexOf(".")+1, cn.length());
					cn = cn.substring(0,1).toLowerCase()+cn.substring(1,cn.length());
					clazz.setName(cn);
				}else{
					clazz.setName(type.value());
				}
				
				//获取类所有方法
				Method[] methods = clazz.getClazz().getDeclaredMethods();
				//获取所有类成员变量
				Field[] fields = clazz.getClazz().getDeclaredFields();
				
				List<Method> listMethods = Arrays.asList(methods);
				
				listMethods.forEach(method ->{
					web.annotation.Method m = method.getAnnotation(web.annotation.Method.class);
					//过滤有注解标签的方法
					if(m != null){
						mapMethod.put(m.value(), method);//保存方法别名
						mapMReturnType.put(m.value(), m.isReturnPage());//保存方法返回类型：是否为JSP
						List<String> params = new ArrayList<>();
						
						Parameter[] allParameters = method.getParameters();//获取所有的参数
						
						//过滤参数注解
						for(Parameter param:allParameters){
							Param p = param.getAnnotation(Param.class);
							if(p!= null){
								params.add(p.value());
							}
						}
						mapParam.put(m.value(), params);
					}else{
						//过滤Controller里面的get方法 用于为request set值
						String mName = method.getName();//获取方法名
						if(mName.startsWith("get")){
							mName = mName.substring(3,mName.length());
							for(Field field:fields){
								if(mName.toLowerCase().equals(field.getName().toLowerCase())){
									members.put(field.getName(),method);
									break;
								}
							}
						}
					}
					clazz.setMethod(mapMethod);
					clazz.setmReturnType(mapMReturnType);
					clazz.setParams(mapParam);
				});
				clazz.setMembers(members);
				sets.add(clazz);
			}
				
		});
		return sets;
	}
	
}
 